package jscinttools.utilities.jhplotutilities;

import java.lang.String;
import java.lang.System;
import jhplot.H1D;
import jhplot.P1D;
import jhplot.P0D;

/**
 *  Some Static Methods for the JHPlot Classes
 *
 *@author     marc-antoine
 *@created    5 avril 2011
 */
public class JHPlotUtil
{

	/**
	 *  Constructor for the JHPlotUtil object
	 */
	private JHPlotUtil() { }

	public static double maxBinHeight(H1D h1d, double min, double max){
		double[] binCenters = h1d.binCenters();
		double[] binHeights = h1d.binHeights();
		P0D p0d = new P0D();
		for (int i = 0; i < binCenters.length; i++){
			if (binCenters[i] >= min && binCenters[i] <= max)
				p0d.add(binHeights[i]);
		}
		return p0d.getMax();
	}

	/**
	 *  Fusion two P1Ds and sort them along the X axis (ascending order)
	 *
	 *@param  p1d1    The first P1D
	 *@param  p1d2    The second P1D
	 *@param  title   The title of the fusioned P1D
	 *@param  sortup  Description of the Parameter
	 *@return         The fusioned P1D
	 */
	public static P1D fusion(P1D p1d1, P1D p1d2, String title, boolean sortup)
	{
		//double[] p1d1X = p1d1.getArrayX();
		//double[] p1d1XL = p1d1.getArrayXleft();
		//double[] p1d1XR = p1d1.getArrayXright();
		//double[] p1d1XLS = p1d1.getArrayXleftSys();
		//double[] p1d1XRS = p1d1.getArrayXrightSys();
		//double[] p1d1Y = p1d1.getArrayY();
		//double[] p1d1YU = p1d1.getArrayYupper();
		//double[] p1d1YL = p1d1.getArrayYlower();
		//double[] p1d1YUS = p1d1.getArrayYupperSys();
		//double[] p1d1YLS = p1d1.getArrayYlowerSys();
		//
		//double[] p1d2X = p1d2.getArrayX();
		//double[] p1d2XL = p1d2.getArrayXleft();
		//double[] p1d2XR = p1d2.getArrayXright();
		//double[] p1d2XLS = p1d2.getArrayXleftSys();
		//double[] p1d2XRS = p1d2.getArrayXrightSys();
		//double[] p1d2Y = p1d2.getArrayY();
		//double[] p1d2YU = p1d2.getArrayYupper();
		//double[] p1d2YL = p1d2.getArrayYlower();
		//double[] p1d2YUS = p1d2.getArrayYupperSys();
		//double[] p1d2YLS = p1d2.getArrayYlowerSys();

		int size1 = p1d1.size();
		int size2 = p1d2.size();

		double[] p1dX = new double[size1 + size2];
		double[] p1dXL = new double[size1 + size2];
		double[] p1dXR = new double[size1 + size2];
		double[] p1dXLS = new double[size1 + size2];
		double[] p1dXRS = new double[size1 + size2];
		double[] p1dY = new double[size1 + size2];
		double[] p1dYU = new double[size1 + size2];
		double[] p1dYL = new double[size1 + size2];
		double[] p1dYUS = new double[size1 + size2];
		double[] p1dYLS = new double[size1 + size2];

		for (int i = 0; i < size1; i++)
		{
			p1dX[i] = p1d1.getX(i);
			p1dXL[i] = p1d1.getXleft(i);
			p1dXR[i] = p1d1.getXright(i);
			p1dXLS[i] = p1d1.getXleftSys(i);
			p1dXRS[i] = p1d1.getXrightSys(i);
			p1dY[i] = p1d1.getY(i);
			p1dYU[i] = p1d1.getYupper(i);
			p1dYL[i] = p1d1.getYlower(i);
			p1dYUS[i] = p1d1.getYupperSys(i);
			p1dYLS[i] = p1d1.getYlowerSys(i);
		}

		for (int i = 0; i < size2; i++)
		{
			p1dX[i + size1] = p1d2.getX(i);
			p1dXL[i + size1] = p1d2.getXleft(i);
			p1dXR[i + size1] = p1d2.getXright(i);
			p1dXLS[i + size1] = p1d2.getXleftSys(i);
			p1dXRS[i + size1] = p1d2.getXrightSys(i);
			p1dY[i + size1] = p1d2.getY(i);
			p1dYU[i + size1] = p1d2.getYupper(i);
			p1dYL[i + size1] = p1d2.getYlower(i);
			p1dYUS[i + size1] = p1d2.getYupperSys(i);
			p1dYLS[i + size1] = p1d2.getYlowerSys(i);
		}
		if (sortup)
		{
			int size = size1 + size2;
			for (int i = 0; i < size - 1; i++)
			{
				int k = i;
				for (int j = 0; j < (size - k - 1); j++)
				{
					//System.out.println("k=" + k);
					//System.out.println("size" + size);
					//System.out.println(" j=" + j);
					if (p1dX[j] > p1dX[j + 1])
					{
						double p1djX = p1dX[j];
						double p1djXL = p1dXL[j];
						double p1djXR = p1dXR[j];
						double p1djXLS = p1dXLS[j];
						double p1djXRS = p1dXRS[j];
						double p1djY = p1dY[j];
						double p1djYU = p1dYU[j];
						double p1djYL = p1dYL[j];
						double p1djYUS = p1dYUS[j];
						double p1djYLS = p1dYLS[j];

						double p1dj1X = p1dX[j + 1];
						double p1dj1XL = p1dXL[j + 1];
						double p1dj1XR = p1dXR[j + 1];
						double p1dj1XLS = p1dXLS[j + 1];
						double p1dj1XRS = p1dXRS[j + 1];
						double p1dj1Y = p1dY[j + 1];
						double p1dj1YU = p1dYU[j + 1];
						double p1dj1YL = p1dYL[j + 1];
						double p1dj1YUS = p1dYUS[j + 1];
						double p1dj1YLS = p1dYLS[j + 1];

						p1dX[j] = p1dj1X;
						p1dXL[j] = p1dj1XL;
						p1dXR[j] = p1dj1XR;
						p1dXLS[j] = p1dj1XLS;
						p1dXRS[j] = p1dj1XRS;
						p1dY[j] = p1dj1Y;
						p1dYU[j] = p1dj1YU;
						p1dYL[j] = p1dj1YL;
						p1dYUS[j] = p1dj1YUS;
						p1dYLS[j] = p1dj1YLS;

						p1dX[j + 1] = p1djX;
						p1dXL[j + 1] = p1djXL;
						p1dXR[j + 1] = p1djXR;
						p1dXLS[j + 1] = p1djXLS;
						p1dXRS[j + 1] = p1djXRS;
						p1dY[j + 1] = p1djY;
						p1dYU[j + 1] = p1djYU;
						p1dYL[j + 1] = p1djYL;
						p1dYUS[j + 1] = p1djYUS;
						p1dYLS[j + 1] = p1djYLS;
					}
				}
			}
		}
		P1D p1d = new P1D(title);
		p1d.fill(p1dX, p1dY, p1dXL, p1dXR, p1dYU, p1dYL, p1dXLS, p1dXRS, p1dYUS, p1dYLS);
		//p1d.fill(p1d1X, p1d1Y, p1d1XL, p1d1XR, p1d1YU, p1d1YL, p1d1XLS, p1d1XRS, p1d1YUS, p1d1YLS);
		//p1d.fill(p1d2X, p1d2Y, p1d2XL, p1d2XR, p1d2YU, p1d2YL, p1d2XLS, p1d2XRS, p1d2YUS, p1d2YLS);


		//return sortup(p1d);
		//else
		return p1d;
	}


	/**
	 *  Fusion two P1Ds and sort them along the X axis (ascending order)
	 *
	 *@param  p1d1    The first P1D
	 *@param  p1d2    The second P1D
	 *@param  sortup  Description of the Parameter
	 *@return         The fusioned P1D
	 */
	public static P1D fusion(P1D p1d1, P1D p1d2, boolean sortup)
	{
		return fusion(p1d1, p1d2, "", sortup);
	}


	/**
	 *  Description of the Method
	 *
	 *@param  p1d1  Description of the Parameter
	 *@param  p1d2  Description of the Parameter
	 *@return       Description of the Return Value
	 */
	public static P1D fusion(P1D p1d1, P1D p1d2)
	{
		return fusion(p1d1, p1d2, "", true);
	}


	/**
	 *  Sort up a P1D along the X axis (ascending order)
	 *
	 *@param  p1d  the P1D to sort up
	 *@return      the P1D sorted up
	 */
	public static P1D sortup(P1D p1d)
	{
		System.out.println("p1d.size()=" + p1d.size());
		int size = p1d.size();
		for (int i = 0; i < size - 1; i++)
		{
			int k = i;
			for (int j = 0; j < (size - k - 1); j++)
			{
				System.out.println("k=" + k);
				System.out.println("size" + size);
				System.out.println(" j=" + j);
				if (p1d.getX(j) > p1d.getX(j + 1))
				{
					double p1djX = p1d.getX(j);
					double p1djXL = p1d.getXleft(j);
					double p1djXR = p1d.getXright(j);
					double p1djXLS = p1d.getXleftSys(j);
					double p1djXRS = p1d.getXrightSys(j);
					double p1djY = p1d.getY(j);
					double p1djYU = p1d.getYupper(j);
					double p1djYL = p1d.getYlower(j);
					double p1djYUS = p1d.getYupperSys(j);
					double p1djYLS = p1d.getYlowerSys(j);

					double p1dj1X = p1d.getX(j + 1);
					double p1dj1XL = p1d.getXleft(j + 1);
					double p1dj1XR = p1d.getXright(j + 1);
					double p1dj1XLS = p1d.getXleftSys(j + 1);
					double p1dj1XRS = p1d.getXrightSys(j + 1);
					double p1dj1Y = p1d.getY(j + 1);
					double p1dj1YU = p1d.getYupper(j + 1);
					double p1dj1YL = p1d.getYlower(j + 1);
					double p1dj1YUS = p1d.getYupperSys(j + 1);
					double p1dj1YLS = p1d.getYlowerSys(j + 1);

					p1d.set(j, p1dj1X, p1dj1Y, p1dj1XL, p1dj1XR, p1dj1YU, p1dj1YL, p1dj1XLS, p1dj1XRS, p1dj1YUS, p1dj1YLS);
					p1d.set(j + 1, p1djX, p1djY, p1djXL, p1djXR, p1djYU, p1djYL, p1djXLS, p1djXRS, p1djYUS, p1djYLS);
				}
			}
		}
		return p1d;
	}


	/**
	 *  Description of the Method
	 *
	 *@param  p1d1  Description of the Parameter
	 *@param  p1d2  Description of the Parameter
	 *@return       Description of the Return Value
	 */
	public static P1D divide(P1D p1d1, P1D p1d2)
	{
		P1D p1d = new P1D("");
		for (int i = 0; i < p1d1.size(); i++)
		{
			int j = 0;
			while (p1d2.getX(j) != p1d1.getX(i))
			{

				j++;
			}
			if (p1d2.getX(j) == p1d1.getX(i))
			{
				//if (i == 0)
				//{
				//	System.out.println(p1d1.getX(i) + "\n" + p1d2.getX(j) + "\n" + j + "\n" + "########");
				//}
				if (p1d2.getY(j) != 0)
				{
					p1d.add(
							p1d1.getX(i)
							, p1d1.getY(i) / p1d2.getY(j)
					//, p1d1.getXleft(i)
					//, p1d1.getXright(i)
					//, p1d1.getYupper(i) / p1d2.getYupper(j)
					//, p1d1.getYlower(i) / p1d2.getYlower(j)
					//, p1d1.getXleftSys(i)
					//, p1d1.getXrightSys(i)
					//, p1d1.getYupperSys(i) / p1d2.getYupperSys(j)
					//, p1d1.getYlowerSys(i) / p1d2.getYlowerSys(j)
							);
					//System.out.println(p1d.getX(i) + "\n" + p1d.getY(j) + "\n" + i + "\n" + j + "\n" + "########");
				}
			}
		}
		return p1d;
	}


	/**
	 *  Description of the Method
	 *
	 *@param  p1d   Description of the Parameter
	 *@param  nMoy  Description of the Parameter
	 *@return       Description of the Return Value
	 */
	public static P1D smooth(P1D p1d, int nMoy)
	{
		if (nMoy == 0)
		{
			System.out.println("The Spectrum will not be smoothed");
			return p1d;
		}
		else
		{
			//P1D smoothedP1D = new P1D(p1d.getTitle());
			P1D smoothedP1D = new P1D("");
			int size = p1d.size();
			for (int j = 0; j < size; j++)
			{
				if (((j >= (nMoy - 1) / 2)) && (j < (size - ((nMoy - 1) / 2))))
				{
					double moy = 0;
					for (int k = -(nMoy - 1) / 2; k < (nMoy + 1) / 2; k++)
					{
						double y = p1d.getY(j + k);
						moy += y;
					}
					double x = p1d.getX(j);
					smoothedP1D.add(x, (moy / nMoy));
				}
			}
			return smoothedP1D;
		}
	}
}

